﻿
namespace NamedBinaryTag
{
	/// <summary>
	/// Represents a Tag with a Name.
	/// </summary>
	public abstract class NamedTag : ITag, System.ComponentModel.INotifyPropertyChanged
	{
		#region ITag Members

		abstract public byte TagType
		{
			get;
		}

		public string Name
		{
			get
			{
				if (_name == null)
					return string.Empty;
				return _name.Value;
			}
			set
			{
				if (_name == null)
					_name = new TagString();
				if (_name.Value != value)
				{
					_name.Value = value;
					RaisePropertyChange("Name");
				}
			}
		}

		public void Read(System.IO.BinaryReader input)
		{
			Read(input, false);
		}

		public void Write(System.IO.BinaryWriter output)
		{
			Write(output, false);
		}

		#endregion

		private TagString _name;

		/// <summary>
		/// Reads the current tag data from the specified <see cref="System.IO.BinaryReader"/>.
		/// </summary>
		/// <param name="input">The <see cref="System.IO.BinaryReader"/> from which to read.</param>
		/// <param name="ignoreName">Wether to read the name of the Tag or not.</param>
		/// <remarks>
		/// The read Tag may not have a Name in some situations.
		/// </remarks>
		public virtual void Read(System.IO.BinaryReader input, bool ignoreName)
		{
			if (!ignoreName)
			{
				if (_name == null)
					_name = new TagString();
				_name.Read(input, true);
			}
		}

		/// <summary>
		/// Writes the current tag data to the specified <see cref="System.IO.BinaryWriter"/>.
		/// </summary>
		/// <param name="output">The <see cref="System.IO.BinaryWriter"/> in which to write.</param>
		/// <param name="ignoreName">Wether to write the name of the Tag or not.</param>
		/// <remarks>
		/// The wrote Tag may not have to have a Name in some situations.
		/// </remarks>
		public virtual void Write(System.IO.BinaryWriter output, bool ignoreName)
		{
			if (!ignoreName)
			{
				if (_name == null)
				{
					TagString tmp = new TagString();
					tmp.Write(output, true);
				}
				else
					_name.Write(output, true);
			}
		}

		#region INotifyPropertyChanged Members

		public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

		#endregion

		protected void RaisePropertyChange(string propertyName)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
		}
	}
}
